<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/2/28 0028
 * Time: 22:28
 */


/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/2/26 0026
 * Time: 22:21
 */
class Worker
{

    protected $socket;

    public $connect;

    public $message;

    public $allSocket; //保存所有的socket

    public function __construct($socket_address)
    {
        $this->socket = stream_socket_server($socket_address);
        stream_set_blocking($this->socket, 0);
        $this->allSocket[(int)$this->socket] = $this->socket;
    }

    public function accept()
    {
        while (1) {
            $write = $except = [];
            //需要监听socket

            $read = $this->allSocket;
            //内核select 监听状态的改变
            stream_select($read, $write, $except, 60);
            foreach ($read as $index => $item) {
                var_dump($item);
                //当前发生改变的为服务端
                if ($item === $this->socket) {
                    $client = stream_socket_accept($this->socket);//阻塞监听
                    if ($client && is_callable($this->connect)) {
                        call_user_func_array($this->connect, array($client, '触发连接'));
                    }
                    $this->allSocket[(int)$client] = $client;
                } else {
                    //客户端scoket
                    $buffer = fread($item, 65535);
//                    var_dump(empty($buffer));
                    if (empty($buffer)) {
                        if (feof($item) || !($item)) {
                            //出发关闭
                            if (!empty($buffer) && is_callable($this->message)) {
                                call_user_func_array($this->message, array($item, '触发消息事件'));
                            }

                            unset($this->allSocket[(int)$item]);
                        }
                    }

                }
            }
            //怎么区分客户端和服务端
//            if (pcntl_fork() == 0) {
//
//                $client = stream_socket_accept($this->socket);
//                if ($client && is_callable($this->connect)) {
//                    call_user_func_array($this->connect, array($client, '触发连接'));
//                }
//                $clientData = fread($client, 65535);
//                if (!empty($clientData) && is_callable($this->message)) {
//                    call_user_func_array($this->message, array($client, '触发消息事件'));
//                }
//                fclose($client);
//            }
        }
    }

    public function fork()
    {

        $this->accept();

    }

    public function start()
    {
        $this->fork();

    }

}

$worker = new Worker('tcp://0.0.0.0:9501');

$worker->connect = function ($client, $args) {
    var_dump($client, $args);
};
$worker->message = function ($client, $args) {
//    var_dump($client, $args);
    $out = "HTTP/1.1\r\n";
    $out .= "Host: test.com\r\n";

    $out .= "name:longqiqi\r\n";
    $out .= "Connection: Close\r\n\r\n";

    fwrite($client, $out);
    fclose($client);
};
$worker->start();